1 00:00:00,540 --> 00:00:04,350 So in our last lecture, we filled out our custom tween service. 2 00:00:04,350 --> 00:00:09,240 We called Better Tween to allow us to create tweens on the server that have their effects applied. 3 00:00:09,240 --> 00:00:11,640 After all, clients have played the tween on their end. 4 00:00:11,640 --> 00:00:17,460 Now we can go ahead and get started creating and scripting the custom door system that will be responsible 5 00:00:17,460 --> 00:00:22,290 for handling all of these nice doors in our game, and we're going to be using our better tween module 6 00:00:22,290 --> 00:00:27,450 script to create smooth tweens that get applied on both the client and on the server. 7 00:00:27,720 --> 00:00:32,280 So we can go ahead and go into our server script service and open up the module script that will be 8 00:00:32,280 --> 00:00:35,370 responsible for handling the doors, which is our door service. 9 00:00:35,730 --> 00:00:38,070 Inside of here, we're going to need three services. 10 00:00:38,070 --> 00:00:40,230 One is going to be replicated storage. 11 00:00:43,150 --> 00:00:46,180 We're going to need the server storage service. 12 00:00:48,300 --> 00:00:51,990 And lastly, we're going to need the server script service. 13 00:00:57,920 --> 00:01:04,220 Now we're also going to be using the service to act as a class for creating new door objects. 14 00:01:04,220 --> 00:01:08,060 So every single door in our game is stored in a folder called doors. 15 00:01:08,060 --> 00:01:13,730 And when this service gets started, we're going to loop through all of the doors in our game and create 16 00:01:13,730 --> 00:01:19,640 and set up these custom door objects based on the models and based on the attributes that are given 17 00:01:19,640 --> 00:01:21,080 for these different doors. 18 00:01:21,080 --> 00:01:24,020 So as you can see, some of these doors have different attributes. 19 00:01:24,020 --> 00:01:30,860 For example, this locked door that we have in our basement requires a key, and the key name is provided 20 00:01:30,860 --> 00:01:31,700 here as well. 21 00:01:31,700 --> 00:01:37,160 We also have added an attribute on these doors to define whether or not some of them are one way. 22 00:01:37,160 --> 00:01:43,400 So for example, the doors inside of our stalls only go one way, and we've defined a one way rotation 23 00:01:43,400 --> 00:01:46,790 for these doors into which direction they must rotate. 24 00:01:47,030 --> 00:01:51,950 So inside of the service we're going to have the table to represent the service. 25 00:01:51,950 --> 00:01:57,560 But we're also going to have a table to represent the meta table that will be attached to custom objects 26 00:01:57,560 --> 00:01:58,970 created by our service. 27 00:01:58,970 --> 00:02:01,490 And we can return our door service at the end here. 28 00:02:01,970 --> 00:02:03,350 Now inside of our meta table. 29 00:02:03,350 --> 00:02:08,630 We need to, of course, make sure that we set the underscore underscore index meta method equal to 30 00:02:08,630 --> 00:02:10,970 the door service meta table. 31 00:02:11,180 --> 00:02:14,930 And then from this point we can start referencing a bunch of other different things. 32 00:02:14,960 --> 00:02:18,290 The first thing that we can reference is our better tween module script. 33 00:02:18,290 --> 00:02:25,730 And that's going to be inside of server script service dot server dot modules dot better tween. 34 00:02:25,940 --> 00:02:29,240 We can then also reference our update guy event. 35 00:02:29,240 --> 00:02:34,340 And we're going to be using this to communicate messages to players when they try to interact with something 36 00:02:34,340 --> 00:02:35,810 like a lock door. 37 00:02:35,810 --> 00:02:39,980 And that means we're going to have to also require our G actions enum. 38 00:02:39,980 --> 00:02:44,720 That way we can stay consistent with the actions we want to send to the clients. 39 00:02:45,260 --> 00:02:47,150 So G actions enum. 40 00:02:48,080 --> 00:02:51,860 There is an event inside of server storage called Door Event. 41 00:02:51,860 --> 00:02:53,870 And this is a Bindable event. 42 00:02:54,500 --> 00:02:59,570 And we're going to use this event to allow different server scripts, no matter what script they're 43 00:02:59,570 --> 00:03:05,450 located in, to reference this event and control doors from their end without having to interact with 44 00:03:05,450 --> 00:03:08,150 this service or require this service directly. 45 00:03:08,150 --> 00:03:13,370 Some other references we're going to make are some sound instances that we have stored in replicated 46 00:03:13,370 --> 00:03:14,030 storage. 47 00:03:14,030 --> 00:03:18,590 So we're going to use these sound instances to play them on the doors directly. 48 00:03:18,590 --> 00:03:21,020 So when we open a door we'll play this sound. 49 00:03:21,080 --> 00:03:23,420 When we close the door we'll play this one. 50 00:03:23,840 --> 00:03:26,660 And when we unlock a door we'll play this sound. 51 00:03:27,990 --> 00:03:28,830 Just like that. 52 00:03:28,830 --> 00:03:30,780 So we'll make a reference to each one of those. 53 00:03:30,780 --> 00:03:36,540 We'll have a door open, sound, replicated storage instances, sounds, door open. 54 00:03:36,540 --> 00:03:40,200 We'll have our door close sound. 55 00:03:43,060 --> 00:03:46,750 And we're also going to have a reference to our door unlock sound. 56 00:03:51,290 --> 00:03:51,980 Okay. 57 00:03:51,980 --> 00:03:55,160 Now we're going to have to create a table and I'm going to call it current doors. 58 00:03:55,190 --> 00:03:59,510 And this will store all of the door objects that we have currently created in our game. 59 00:03:59,510 --> 00:04:03,230 And this is serving as our cache for storing all of these door objects. 60 00:04:03,380 --> 00:04:06,560 And the last but not least, we're going to have one constant. 61 00:04:06,560 --> 00:04:11,810 And this constant is going to define how long we should tween the doors for. 62 00:04:11,810 --> 00:04:14,510 And we're going to call this door move duration. 63 00:04:14,510 --> 00:04:16,760 And we're just going to set it to one second. 64 00:04:16,790 --> 00:04:19,550 You can of course adjust this value to whatever you'd like. 65 00:04:19,550 --> 00:04:22,610 But I found one second to work best for all of our doors. 66 00:04:22,640 --> 00:04:29,150 Now, some private functions that we're going to need for our door service is one to play sounds. 67 00:04:29,150 --> 00:04:33,710 So we'll call it play sound and we'll get past a sound instance here. 68 00:04:35,320 --> 00:04:36,370 Sound. 69 00:04:36,930 --> 00:04:40,950 And we'll get told the parent we want to set for this sound. 70 00:04:41,700 --> 00:04:48,540 We'll have a function for when a prompt gets triggered in our game, or when a prompt on our door gets 71 00:04:48,540 --> 00:04:51,210 triggered so we can call it on triggered. 72 00:04:52,100 --> 00:04:57,830 And then we're going to need a function to listen to that bindable event that might get fired by other 73 00:04:57,830 --> 00:05:03,320 scripts in our game, so we can call it on door event, and this will get passed an action and arguments 74 00:05:03,320 --> 00:05:04,820 to go along with that action. 75 00:05:04,820 --> 00:05:09,530 Now, since this service is also going to be acting as a class, we of course need a constructor. 76 00:05:09,530 --> 00:05:13,190 So inside of our door service we can create a new constructor. 77 00:05:13,190 --> 00:05:17,570 And all this function is going to be passed is a model that represents the door. 78 00:05:17,570 --> 00:05:21,980 So we're basically just going to loop through every single door inside of our Krusty Krab. 79 00:05:21,980 --> 00:05:26,930 Pass the model to this constructor, and this will take care of the rest for us. 80 00:05:26,930 --> 00:05:29,720 So we can create a table in here called self. 81 00:05:30,290 --> 00:05:32,060 This will represent our object. 82 00:05:32,060 --> 00:05:37,070 And then inside of self we can set a reference to the door model which is equal to door model. 83 00:05:37,340 --> 00:05:40,130 We can set the type equal to the door models. 84 00:05:40,130 --> 00:05:43,490 Attribute of get attribute door type. 85 00:05:44,310 --> 00:05:52,110 We can set the property of one way equal to the door model, get attribute one way if it has one. 86 00:05:52,110 --> 00:05:55,890 If it doesn't, then we can just set it to false using the Or statement. 87 00:05:56,280 --> 00:06:04,920 If this door is one way, then we can set a property called one way rotation inside of our object. 88 00:06:04,920 --> 00:06:09,990 So door model get attribute one way rotation. 89 00:06:10,770 --> 00:06:14,880 We'll then create a references to the two different prompts that are going to be in our door. 90 00:06:14,880 --> 00:06:20,760 So we'll have prompt number one equal to door model dot prompt part. 91 00:06:20,940 --> 00:06:25,200 So there's a part inside of each one of our doors called prompt part. 92 00:06:25,200 --> 00:06:29,820 And it has attachments in here that store the two different proximity prompts. 93 00:06:29,820 --> 00:06:35,940 Because the plan for our doors is will have a proximity prompt on this side and on this side. 94 00:06:35,940 --> 00:06:40,140 And depending on which one gets triggered, we'll open the door in the appropriate direction. 95 00:06:40,140 --> 00:06:45,000 So if we activate the prompt on this side, the door is going to swing that way. 96 00:06:45,000 --> 00:06:49,260 But if we trigger the prompt on this side, then the door is going to swing the other way. 97 00:06:49,260 --> 00:06:52,140 That way the door actually doesn't rotate into the player. 98 00:06:52,140 --> 00:06:57,750 So we can reference our prompt part and get attachment one, which represents the first part, and get 99 00:06:57,750 --> 00:07:00,090 the proximity prompt inside of it. 100 00:07:00,840 --> 00:07:04,800 And then we're going to do the exact same thing for prompt number two. 101 00:07:04,920 --> 00:07:09,360 So we'll just copy this to prompt two and reference attachment number two. 102 00:07:09,780 --> 00:07:13,740 We're going to have a property in here to keep track of whether or not the door is locked. 103 00:07:13,740 --> 00:07:20,520 So we could do door model get attribute locked or we set it to false by default. 104 00:07:21,390 --> 00:07:30,120 We'll do self dot requires key equal to door model get attribute requires key or the default will be 105 00:07:30,120 --> 00:07:31,230 false as well. 106 00:07:31,680 --> 00:07:34,860 And if self dot requires key is true. 107 00:07:35,650 --> 00:07:42,130 Then we can set the property of key name equal to the door model. 108 00:07:42,130 --> 00:07:45,070 Get attribute key name. 109 00:07:45,770 --> 00:07:50,750 Then we're going to have a couple other properties, one that will keep track of whether or not the 110 00:07:50,750 --> 00:07:53,060 door is open by default. 111 00:07:53,060 --> 00:07:53,780 That is false. 112 00:07:53,780 --> 00:07:58,910 And then we'll keep track of whether or not the door is moving, and we'll set that to false as well. 113 00:07:59,510 --> 00:08:04,820 Now based on the two different type attributes that we set up here, we're going to have to do something 114 00:08:04,820 --> 00:08:08,360 slightly different when referencing the hinges in the door. 115 00:08:08,390 --> 00:08:14,150 So basically, there's an invisible part back here that the door is going to rotate along with. 116 00:08:14,150 --> 00:08:18,170 So this hinge is the part that we need to rotate to move our door. 117 00:08:18,200 --> 00:08:24,530 Now single doors have one hinge, while double doors like these ones are going to have two hinges, 118 00:08:24,530 --> 00:08:25,850 one for each side. 119 00:08:26,030 --> 00:08:34,550 So if the type of our door is equal to single, then all we need to do is create one property that will 120 00:08:34,550 --> 00:08:41,480 refer to the original hinge, and we need to store the original hinges sea frame. 121 00:08:41,480 --> 00:08:48,350 That way we can always keep track of what the original position was for when the hinge needs to close. 122 00:08:48,350 --> 00:08:52,640 So we can call this original hinge sea frame. 123 00:08:52,640 --> 00:08:57,140 And that's going to be equal to self dot door model dot hinge. 124 00:08:57,470 --> 00:08:59,390 And we get the sea frame of the hinge. 125 00:09:01,160 --> 00:09:01,760 Otherwise. 126 00:09:01,760 --> 00:09:06,980 If the type of our door is equal to double, then we need to create two of these properties. 127 00:09:06,980 --> 00:09:08,360 So we'll just copy this. 128 00:09:08,390 --> 00:09:11,690 We'll have original hinge one see frame. 129 00:09:14,120 --> 00:09:19,910 And then we can have originals, hinge two C frame, and then we'll just make this one refer to hinge 130 00:09:19,910 --> 00:09:20,570 number one. 131 00:09:20,570 --> 00:09:22,940 And this one will refer to hinge number two. 132 00:09:23,950 --> 00:09:29,980 Now that we have all these properties set up, we need to connect some functions to events inside of 133 00:09:29,980 --> 00:09:35,980 our proximity prompts so we can do self dot prompt one dot triggered. 134 00:09:35,980 --> 00:09:39,010 We want to connect a lambda function to this. 135 00:09:39,010 --> 00:09:41,800 That will get the player that triggered the proximity prompt. 136 00:09:41,800 --> 00:09:45,520 And then we can call our on triggered function and pass. 137 00:09:45,790 --> 00:09:48,820 Um, we want to pass the object itself. 138 00:09:49,360 --> 00:09:52,270 We want to pass which prompt got triggered. 139 00:09:52,270 --> 00:09:57,100 So that way uh, our door will know which direction to swing in. 140 00:09:57,100 --> 00:10:00,850 So self dot prompt one is the one that got triggered here. 141 00:10:00,850 --> 00:10:05,440 And then we're going to pass the player that uh activated this prompt. 142 00:10:05,440 --> 00:10:09,490 And then we can basically just copy this and do the exact same thing for prompt number two. 143 00:10:09,520 --> 00:10:14,290 But instead we need to pass self dot prompt two as the prompt that got triggered. 144 00:10:14,290 --> 00:10:21,370 Then at the very end here we can set the meta table on our object to the door service meta table. 145 00:10:21,370 --> 00:10:27,880 And then we can insert our object into the current doors table and then return self at the very end 146 00:10:27,880 --> 00:10:30,580 of our constructor if we need to. 147 00:10:31,270 --> 00:10:34,330 And I really do not like this Roblox bug. 148 00:10:34,330 --> 00:10:36,100 This is a new bug that's happening. 149 00:10:37,540 --> 00:10:43,180 Now another function that I want this service to have and not the objects themselves, is I want to 150 00:10:43,180 --> 00:10:49,270 have a function to be able to get a door object based on a model provided. 151 00:10:49,270 --> 00:10:55,960 So we're going to call this door service get door object from model. 152 00:10:56,140 --> 00:11:01,300 So in case we need to grab a door object but we only have the model, then we could do is we could get 153 00:11:01,300 --> 00:11:03,160 the model passed to this function. 154 00:11:03,400 --> 00:11:08,050 And then we'll just loop through every single door in our current doors table. 155 00:11:08,710 --> 00:11:14,230 And we're going to check if this door door model is equal to the model passed to this function. 156 00:11:16,970 --> 00:11:20,120 If it is, then we can just return this door object. 157 00:11:21,610 --> 00:11:24,100 Otherwise we won't return anything at all. 158 00:11:24,730 --> 00:11:30,190 Now, what are some functions that doors in our door service need to have? 159 00:11:30,220 --> 00:11:33,910 Well, first we need a function to actually open a door. 160 00:11:33,910 --> 00:11:38,080 So door service made a table open. 161 00:11:38,380 --> 00:11:41,410 And this function will get passed the prompt that was triggered. 162 00:11:41,410 --> 00:11:43,420 So we could just call it triggered prompt. 163 00:11:43,870 --> 00:11:46,540 We need a function to close a door. 164 00:11:46,540 --> 00:11:49,420 So door service meta table close. 165 00:11:49,840 --> 00:11:52,720 We need a function to be able to lock a door. 166 00:11:52,720 --> 00:11:54,940 So door service. 167 00:11:56,050 --> 00:11:58,090 A table lock. 168 00:11:58,090 --> 00:12:01,600 And of course, we'll also need a function to unlock a door. 169 00:12:05,860 --> 00:12:10,660 We'll need a function to disable the prompts or enable the prompts in a door. 170 00:12:10,660 --> 00:12:15,220 So door service meta table enable prompts. 171 00:12:15,920 --> 00:12:17,870 And then disable prompts. 172 00:12:17,870 --> 00:12:25,460 So actually I'll just copy this, paste that here and rename this to Disable prompts. 173 00:12:25,460 --> 00:12:29,960 And I believe that's all of the functions that we're going to need for our door objects. 174 00:12:30,170 --> 00:12:35,210 The last functions that the service itself is going to need of course is an initialize function and 175 00:12:35,210 --> 00:12:36,050 a start function. 176 00:12:36,050 --> 00:12:38,600 So door service init. 177 00:12:39,160 --> 00:12:42,790 And then door service start. 178 00:12:43,030 --> 00:12:47,980 And we can actually fill out these two functions because they should be rather uncomplicated. 179 00:12:47,980 --> 00:12:52,270 So when we want to initialize the service, all we're going to do is we're going to listen to our door 180 00:12:52,270 --> 00:12:53,500 event dot. 181 00:12:53,530 --> 00:12:57,010 Event and connect our on door event function to it. 182 00:12:57,220 --> 00:13:01,480 And then for the start, all we're going to do in here is we're going to loop through every single door 183 00:13:01,480 --> 00:13:03,940 model that is inside of the workspace. 184 00:13:03,940 --> 00:13:06,760 Dot Krusty Krab dot doors. 185 00:13:06,760 --> 00:13:13,780 We'll get all those children in there, and then we're just going to use our door service dot new constructor 186 00:13:13,780 --> 00:13:15,850 and pass this door model. 187 00:13:15,850 --> 00:13:19,990 And that way we are enabling all the functionality for this particular door. 188 00:13:20,890 --> 00:13:25,300 So I guess the first function we could go ahead and fill out is our on door event here. 189 00:13:25,300 --> 00:13:28,690 So let's go ahead and scroll up to that private function. 190 00:13:28,960 --> 00:13:35,890 Basically what's going to happen here is that another server script is going to request to do some kind 191 00:13:35,890 --> 00:13:38,020 of action to one of our doors. 192 00:13:38,020 --> 00:13:43,360 And of course, since only the door objects are being stored in this script, uh, that other script 193 00:13:43,360 --> 00:13:48,010 isn't going to know exactly the door object, uh, for this particular door model. 194 00:13:48,010 --> 00:13:51,820 So instead, it'll pass to us the model of the door they'd wish to effect. 195 00:13:51,820 --> 00:13:57,850 And then that's why we use our get door object from model function to, you know, find the particular 196 00:13:57,850 --> 00:13:58,990 object for that door. 197 00:13:58,990 --> 00:14:05,710 So what we could do is we could get the door from our door service. 198 00:14:05,770 --> 00:14:11,170 Get door object from model and inside of the arguments passed to this function, we could just basically 199 00:14:11,170 --> 00:14:15,250 have a key that represents the door model we wish to effect. 200 00:14:15,910 --> 00:14:19,900 And then we can check if this door object exists or not. 201 00:14:19,900 --> 00:14:22,450 So if it doesn't then we'll just return. 202 00:14:22,930 --> 00:14:26,290 Otherwise we can go ahead and check the actions requested. 203 00:14:26,650 --> 00:14:33,130 So what we could actually do is we could actually create another enum specifically for our door service. 204 00:14:33,130 --> 00:14:38,710 So inside of service script service, um, inside of our door service, we could create a new module 205 00:14:38,710 --> 00:14:39,580 script in here. 206 00:14:39,580 --> 00:14:45,370 And we can call this door action enums or Door Actions enum. 207 00:14:46,450 --> 00:14:49,840 And let me just find an enum that we've already filled out. 208 00:14:49,840 --> 00:14:57,250 So if we go into replicated storage, um, modules, enums, let me just open up one of these random 209 00:14:57,250 --> 00:14:57,610 ones. 210 00:14:57,610 --> 00:15:01,360 I'll just copy all of this and then just paste it in here. 211 00:15:03,180 --> 00:15:07,320 And the different actions that we could do is we could open a door. 212 00:15:10,030 --> 00:15:12,940 We could close a door. 213 00:15:16,570 --> 00:15:18,880 We could lock a door. 214 00:15:20,270 --> 00:15:23,360 And we can unlock a door. 215 00:15:27,510 --> 00:15:31,110 And I think that's all the actions that we're going to need for now. 216 00:15:31,470 --> 00:15:36,180 So we can go to our door service and basically just require this door actions enum. 217 00:15:36,180 --> 00:15:42,630 So when we refer to our door event, we can just make a reference to Door Actions enum. 218 00:15:42,630 --> 00:15:48,450 And we can just require and refer to the script itself and then Door Actions enum, because it is a 219 00:15:48,450 --> 00:15:49,950 child of this script. 220 00:15:50,250 --> 00:15:55,350 And then we can go back to our on door event function and listen to these different actions. 221 00:15:55,350 --> 00:16:03,600 So if the action requested is equal to the door actions enum dot open door, then we can use this door 222 00:16:03,600 --> 00:16:07,590 object and call the open function on it. 223 00:16:08,110 --> 00:16:13,030 We can do the same thing if the action is equal to door actions. 224 00:16:13,850 --> 00:16:22,190 Enemy closed door do door close if the action is equal to door actions. 225 00:16:22,220 --> 00:16:24,020 Enum dot lock door. 226 00:16:24,020 --> 00:16:27,740 We can, you know, do door lock. 227 00:16:28,540 --> 00:16:35,680 And if the action is equal to door actions enum unlocked door, then we could do door unlock. 228 00:16:35,680 --> 00:16:36,790 Perfect. 229 00:16:37,090 --> 00:16:45,790 Now of course, when we open a door we need to provide which prompts to pass to our open door function, 230 00:16:45,790 --> 00:16:49,330 because this function needs to know which way to swing the door in. 231 00:16:49,360 --> 00:16:57,220 So in this args table, we could also provide a proximity prompt that will act as the prompt that was 232 00:16:57,310 --> 00:16:58,810 technically triggered. 233 00:16:59,110 --> 00:17:05,320 But basically I guess the next functions we can go ahead and fill out are our different functions on 234 00:17:05,320 --> 00:17:06,280 the doors. 235 00:17:06,280 --> 00:17:10,390 So for example, what do we want to do to open a door. 236 00:17:10,420 --> 00:17:16,180 Well, first, before we even open a door we want to check if our door is already open. 237 00:17:16,180 --> 00:17:19,420 So if self dot is open then we're just going to return. 238 00:17:19,420 --> 00:17:21,520 We don't need to open a door that's already open. 239 00:17:21,700 --> 00:17:24,580 Another thing we need to check is if our door is already moving. 240 00:17:24,580 --> 00:17:26,830 So if self dot is moving. 241 00:17:27,880 --> 00:17:29,530 Then we also need to return. 242 00:17:31,100 --> 00:17:34,010 And I believe I need to rename that property here. 243 00:17:34,010 --> 00:17:34,970 So let me do that real quick. 244 00:17:34,970 --> 00:17:37,130 So make sure you change that to is moving. 245 00:17:38,030 --> 00:17:44,330 Otherwise, if all checks out, we can set self dot is moving equal to true and do the same thing for 246 00:17:44,360 --> 00:17:47,750 is open because we're going to be opening the door. 247 00:17:48,580 --> 00:17:53,470 And then we're going to do is we're going to create a new tween info using tween info dot new. 248 00:17:53,470 --> 00:17:55,870 We're going to pass our door move duration. 249 00:17:56,020 --> 00:18:02,470 And then for the easing style I found that an enum dot easing style of sign looks best on our doors. 250 00:18:02,470 --> 00:18:04,780 But of course you can change that to whatever you'd like. 251 00:18:05,410 --> 00:18:10,060 And now when we open the door, we need to check whether or not our door object itself is of the type 252 00:18:10,060 --> 00:18:11,170 single or double. 253 00:18:11,560 --> 00:18:23,620 So if our door is of the type single, then what we need to do is we need to check which prompt was 254 00:18:23,620 --> 00:18:24,250 triggered. 255 00:18:24,250 --> 00:18:29,290 So if the triggered prompt is equal to self dot prompt one. 256 00:18:29,960 --> 00:18:33,800 Then we need to rotate our door along the y axis. 257 00:18:33,920 --> 00:18:35,540 -90 degrees. 258 00:18:35,540 --> 00:18:41,510 So if we go ahead and take a look at like one of our doors here, for example let's look at our prompt 259 00:18:41,510 --> 00:18:41,810 part. 260 00:18:41,810 --> 00:18:43,580 So attachment one is on this side. 261 00:18:43,580 --> 00:18:46,220 So this is attachment or proximity prompt one. 262 00:18:46,220 --> 00:18:49,640 If this gets triggered right then we need to go to our hinge. 263 00:18:49,640 --> 00:18:53,540 And we need to rotate this -90 degrees along the y axis. 264 00:18:53,540 --> 00:18:59,360 So if I go to see frame here and I rotate it -90 degrees, we want our door to open. 265 00:18:59,360 --> 00:19:05,630 That way if the prompt over here gets triggered, then we want to open our door the other way. 266 00:19:05,630 --> 00:19:06,290 Right. 267 00:19:07,540 --> 00:19:09,550 Back into our door service script. 268 00:19:09,550 --> 00:19:16,510 If the triggered prompt is self dot prompt one, then what we need to do is we need to use our better 269 00:19:16,510 --> 00:19:20,710 tween, uh, module script to create a tween on this door. 270 00:19:20,950 --> 00:19:22,600 So I'm going to actually create a variable. 271 00:19:22,600 --> 00:19:24,010 I'm going to call it goal. 272 00:19:24,400 --> 00:19:30,550 And inside of this section we're going to set goal equal to what we want to effect is the C frame of 273 00:19:30,550 --> 00:19:31,630 our hinge. 274 00:19:32,680 --> 00:19:39,040 So we can do self dot door model dot hinge dot c frame. 275 00:19:39,190 --> 00:19:49,870 And we want to add a C frame angles of zero degrees on the x axis, -90 on the y axis and then zero 276 00:19:49,870 --> 00:19:50,830 on the z axis. 277 00:19:50,830 --> 00:19:54,220 And remember c frame dot angles accepts only radians. 278 00:19:54,220 --> 00:19:57,280 So we need to convert this using the math dot rad function. 279 00:19:58,460 --> 00:19:59,000 Perfect. 280 00:19:59,000 --> 00:20:03,020 That's going to be the goal if the prompt triggered was prompt one. 281 00:20:03,890 --> 00:20:10,430 Else if the triggered prompt is equal to self dot prompt number two, then we need to do the exact opposite. 282 00:20:11,110 --> 00:20:16,210 So we need to set this number to 90 degrees instead. 283 00:20:16,660 --> 00:20:21,610 Now another thing we need to check is whether or not our door is one way. 284 00:20:21,610 --> 00:20:24,580 So if, uh, self dot one way. 285 00:20:25,880 --> 00:20:33,050 Then we need to update the goal of the keyframe to instead be the value that was stored in the attribute 286 00:20:33,050 --> 00:20:33,680 for the door. 287 00:20:33,680 --> 00:20:39,320 So for example, with our stall doors, we've defined it that the one way rotation has to be -90 degrees 288 00:20:39,320 --> 00:20:40,580 on the y axis. 289 00:20:40,580 --> 00:20:49,010 So we need to replace this with our self dot one way rotation value. 290 00:20:49,160 --> 00:20:53,000 And we need to of course also convert this into radians. 291 00:20:55,420 --> 00:20:56,170 Alrighty. 292 00:20:56,170 --> 00:21:03,130 And if we were successful in creating a goal table, then we can use our better tween module script 293 00:21:03,130 --> 00:21:04,900 and use our tween function in there. 294 00:21:04,900 --> 00:21:08,110 We want to pass the self dot door model. 295 00:21:08,890 --> 00:21:10,060 That hinge. 296 00:21:11,260 --> 00:21:16,690 We'll pass our tween info that we created, and we're going to pass the goal table that we just created. 297 00:21:16,690 --> 00:21:22,720 And this module script is going to go ahead and take care of all of the animation to give on the client. 298 00:21:22,720 --> 00:21:24,880 So the clients are going to play this tween on their end. 299 00:21:24,880 --> 00:21:28,210 And after that tween is over, then the effects get applied on the server. 300 00:21:28,210 --> 00:21:32,950 So that way we can see the new property applied on both the client and on the server. 301 00:21:33,280 --> 00:21:34,690 Now we need to check. 302 00:21:35,640 --> 00:21:39,480 If the self dot type of our door is equal to double. 303 00:21:39,480 --> 00:21:44,760 If it is, then we need to create two different tweens for both hinges. 304 00:21:44,760 --> 00:21:51,150 So that means we can create a goal for hinge one, and we can create a goal for hinge number two. 305 00:21:51,640 --> 00:21:58,600 So if the triggered prompt is equal to self dot prompt one, then that means the first hinge. 306 00:21:58,600 --> 00:22:02,710 We need to rotate a -90 degrees on the y axis. 307 00:22:02,710 --> 00:22:09,400 And the second hinge we need to rotate 90 degrees on the y axis because they are rotating in opposite 308 00:22:09,400 --> 00:22:10,330 directions. 309 00:22:10,570 --> 00:22:14,770 So goal hinge one can be set to basically what we did here. 310 00:22:14,770 --> 00:22:21,070 But instead the key frame is going to be equal to self dot model dot hinge one dot key frame. 311 00:22:21,070 --> 00:22:23,200 We're going to copy this. 312 00:22:23,200 --> 00:22:25,750 We're going to do the same thing for goal hinge two. 313 00:22:25,750 --> 00:22:27,610 But instead we're going to refer to. 314 00:22:28,290 --> 00:22:29,010 Hinge two. 315 00:22:29,010 --> 00:22:32,070 And then we need to change this to 90 degrees. 316 00:22:33,030 --> 00:22:37,350 Else if the triggered prompt is equal to self dot prompt number two. 317 00:22:38,400 --> 00:22:42,570 Then we're just going to copy this, but we're just going to reverse the role of the numbers. 318 00:22:42,570 --> 00:22:46,050 So this one can be 90 and this one can be -90. 319 00:22:46,260 --> 00:22:50,910 After that if we have goal hinge one and goal hinge two. 320 00:22:52,650 --> 00:23:01,320 Then we can use our better tween to create a new tween on self dot door model dot hinge one. 321 00:23:01,320 --> 00:23:05,130 Pass our tween info and then pass goal for hinge number one. 322 00:23:05,370 --> 00:23:08,940 Copy this and do the exact same thing for hinge number two. 323 00:23:10,880 --> 00:23:15,020 But let me just verify that we got the numbers correct here real quick. 324 00:23:15,020 --> 00:23:20,540 So if we go to our double door, for example, right here, let me select this. 325 00:23:20,870 --> 00:23:24,290 If we take a look at our hinge one. 326 00:23:25,010 --> 00:23:28,160 Oh actually our hinge one is on the left side and not the right side. 327 00:23:28,160 --> 00:23:28,760 Never mind. 328 00:23:28,760 --> 00:23:32,510 So my bad, I thought the hinge one was on the right side. 329 00:23:32,510 --> 00:23:34,910 So instead we actually need to flip these values again. 330 00:23:34,910 --> 00:23:36,620 So this one has to be 90. 331 00:23:36,620 --> 00:23:38,240 This one has to be -90. 332 00:23:38,270 --> 00:23:39,740 This one has to be -90. 333 00:23:39,740 --> 00:23:41,270 And this one has to be 90. 334 00:23:41,600 --> 00:23:49,190 So that means if we activate prompt one on this side hinge number one needs to be rotated 90 degrees 335 00:23:49,190 --> 00:23:49,940 here. 336 00:23:50,150 --> 00:23:56,030 And then hinge number two needs to be rotated -90 degrees just like that. 337 00:23:57,870 --> 00:24:04,770 If the prompt is activated on the other side, then this one needs to be rotated to 90 degrees, and 338 00:24:04,770 --> 00:24:08,160 this one needs to be rotated to -90 degrees. 339 00:24:09,060 --> 00:24:09,990 There we go. 340 00:24:09,990 --> 00:24:10,920 Beautiful. 341 00:24:11,190 --> 00:24:18,630 Now that we have done the tween on the door, we now need to play the sound on the door as well so we 342 00:24:18,630 --> 00:24:20,910 can use our play sound function. 343 00:24:21,150 --> 00:24:25,500 We can pass which sound instance we want to play, which is the door open sound. 344 00:24:26,110 --> 00:24:29,470 And we can pass the parent for where the sound should play. 345 00:24:29,470 --> 00:24:32,530 So we could do self dot door model. 346 00:24:33,210 --> 00:24:36,480 Dot prompt part will play it from the prompt part. 347 00:24:37,810 --> 00:24:40,000 So we'll fill this function out in a moment. 348 00:24:40,000 --> 00:24:44,980 But what we can do after this is we can wait for the door move duration to end. 349 00:24:45,130 --> 00:24:50,230 And once that ends we can set self dot is moving equal to false. 350 00:24:51,290 --> 00:24:56,420 And while our door is actually moving, what we could do before we actually tween the doors is we could 351 00:24:56,420 --> 00:25:01,970 use the Self Disable Prompts function to disable all the prompts on the door, and then when the door 352 00:25:01,970 --> 00:25:05,690 stops moving, then we can re-enable all of the prompts on the door. 353 00:25:06,980 --> 00:25:09,950 So let's go ahead and actually fill out these two functions real quick. 354 00:25:10,640 --> 00:25:19,400 Inside of enable prompts we do self dot prompt one dot enabled equal to true and copy this to the exact 355 00:25:19,400 --> 00:25:20,990 same thing for prompt number two. 356 00:25:20,990 --> 00:25:23,180 And then for disabling the prompts. 357 00:25:23,180 --> 00:25:23,990 It's very easy. 358 00:25:23,990 --> 00:25:26,360 We'll just change these values to false. 359 00:25:27,710 --> 00:25:28,910 Okay, some other functions. 360 00:25:28,910 --> 00:25:32,690 I guess we could just go ahead and fill out real quick is our unlock and lock function. 361 00:25:32,690 --> 00:25:35,120 So these ones are going to be very easy. 362 00:25:35,120 --> 00:25:40,340 All we need to do is set self dot locked equal to true. 363 00:25:40,340 --> 00:25:43,460 And then in here self dot locked equal to false. 364 00:25:43,460 --> 00:25:44,390 Very simple. 365 00:25:45,250 --> 00:25:48,610 The next function we can go ahead and fill out is our Playsound function. 366 00:25:48,640 --> 00:25:55,180 Now, if you remember in our original lobby, we had that module script on the client that received 367 00:25:55,180 --> 00:25:58,750 information from the server onto playing sounds. 368 00:25:58,780 --> 00:26:02,200 Now we're going to do the exact same thing here in our game as well. 369 00:26:02,200 --> 00:26:08,800 We have a sounds handler on the client that's going to handle playing sounds given from the server. 370 00:26:08,800 --> 00:26:13,150 But since we don't have this filled out right now and we're not going to focus on filling it out yet, 371 00:26:13,150 --> 00:26:18,010 this function here, the code that I'm going to put in here is going to act as a placeholder for now. 372 00:26:18,010 --> 00:26:19,930 So we're going to change this in the future. 373 00:26:19,930 --> 00:26:24,430 But just to make sure that everything in our scripts are working well, we could do quickly is just 374 00:26:24,430 --> 00:26:29,020 make a clone of the sound instance that is passed to this function. 375 00:26:29,350 --> 00:26:35,500 We could set the parent of this clone equal to the parent pass of the function, and then what we could 376 00:26:35,500 --> 00:26:42,610 do is set the property like uh sound clone dot play on remove equal to true. 377 00:26:43,520 --> 00:26:46,940 And then we're just going to destroy the sound. 378 00:26:47,210 --> 00:26:50,600 And that way we can test whether or not our door sounds are working. 379 00:26:50,630 --> 00:26:55,700 The next function we can go ahead and fill out is our on triggered function, which gets executed when 380 00:26:55,700 --> 00:26:58,610 a prompts on our doors are triggered. 381 00:26:58,700 --> 00:27:03,830 Because if you remember, we pass to this function the object, the prompt that was triggered and the 382 00:27:03,830 --> 00:27:06,020 player that triggered the prompt. 383 00:27:06,140 --> 00:27:11,390 So what we could do inside of our on triggered function is first, check whether or not our door is 384 00:27:11,390 --> 00:27:11,750 moving. 385 00:27:11,750 --> 00:27:17,990 So if self dot is moving is true, then we're just going to return because we don't want to care. 386 00:27:18,770 --> 00:27:21,170 Oh, and let me define self here in the top. 387 00:27:21,350 --> 00:27:23,630 Let me define the triggered prompt here as well. 388 00:27:23,630 --> 00:27:25,310 And then let me define the player. 389 00:27:26,010 --> 00:27:34,650 Okay, if self not locked is true, then what we can do is we can use our update, GUI event and fire 390 00:27:34,650 --> 00:27:41,100 to this particular player that hey, the door is locked so we can use the GUI actions enum of small 391 00:27:41,100 --> 00:27:47,790 message and we can give some text to this player and say something like the door is locked and then 392 00:27:47,790 --> 00:27:49,830 we can just return out of our function again. 393 00:27:50,400 --> 00:27:55,320 The next thing we could do is we could check if self dot requires key is true. 394 00:27:56,210 --> 00:28:01,130 And if it is, we need to make sure that this player actually doesn't have the key required for this 395 00:28:01,130 --> 00:28:01,880 door. 396 00:28:01,970 --> 00:28:06,200 So if this player does not have the key we required equipped. 397 00:28:06,200 --> 00:28:14,120 So if not player dot character find first child and we pass the self dot key name. 398 00:28:14,120 --> 00:28:20,240 If they don't have this tool with this particular name, then we're also going to use our update guy 399 00:28:20,240 --> 00:28:26,630 event and tell them that the door requires the key. 400 00:28:26,630 --> 00:28:30,590 And we can just concatenate this with the self dot key name. 401 00:28:31,940 --> 00:28:38,510 Also, if we do require the key and the player actually has the key in their inventory, then what we 402 00:28:38,510 --> 00:28:43,760 could do is we could do self dot requires key set that to false because the door is unlocked. 403 00:28:43,760 --> 00:28:46,250 We don't need to require a key anymore. 404 00:28:46,490 --> 00:28:50,990 And then we're going to set self dot locked equal to true. 405 00:28:52,090 --> 00:28:56,470 And then we're going to set on the door model itself. 406 00:28:57,130 --> 00:29:02,320 We're going to set attribute locked equal to true. 407 00:29:03,500 --> 00:29:09,170 And this is because we want to stop the door from moving any further once it's been unlocked, because 408 00:29:09,170 --> 00:29:16,460 inside of our basement, there is one locked door back here that requires a key, and when the player 409 00:29:16,460 --> 00:29:22,040 unlocks it and the door opens, we don't want to allow the players to be able to close the door, because 410 00:29:22,040 --> 00:29:26,510 that means they could just hide in here and the squid where that is hunting them down won't be able 411 00:29:26,510 --> 00:29:30,440 to run and get them in here, or they won't be able to see them either. 412 00:29:30,440 --> 00:29:36,110 Our squid word will be able to pass through doors, but our door won't be able to see them when we fire 413 00:29:36,110 --> 00:29:38,900 raycast because it's just going to hit this door object. 414 00:29:38,900 --> 00:29:44,180 So we don't want them to be able to, you know, close or shut this door once it's been opened. 415 00:29:44,180 --> 00:29:46,550 So that's why we're going to lock the door. 416 00:29:47,240 --> 00:29:52,130 And then we can also play our sound of door unlock sound. 417 00:29:52,430 --> 00:29:58,130 And the parent again is going to be self-taught door model dot for this one we could just do the door 418 00:29:58,130 --> 00:29:58,970 itself. 419 00:29:58,970 --> 00:30:03,230 Now when our prompt is triggered, we need to check whether or not our door is open or closed. 420 00:30:03,230 --> 00:30:09,440 So if self dot is open then we need to use the close function on our door. 421 00:30:10,460 --> 00:30:15,380 Otherwise we'll just use the self dot open function on our door, and we're going to pass the triggered 422 00:30:15,380 --> 00:30:17,210 prompt to our function. 423 00:30:17,690 --> 00:30:20,990 Now the next function we can go ahead and fill out is our close function. 424 00:30:21,940 --> 00:30:23,740 So what do we want to do to close a door? 425 00:30:23,770 --> 00:30:28,900 Well, first we need to check whether or not the door is already closed. 426 00:30:28,900 --> 00:30:31,150 So if not self dot is open. 427 00:30:31,150 --> 00:30:34,090 So if the door is already closed, then we'll just return. 428 00:30:35,170 --> 00:30:39,700 If the door is moving, then we're also going to return. 429 00:30:40,960 --> 00:30:45,820 And then what we're going to do is set self dot is moving equal to true. 430 00:30:45,850 --> 00:30:49,390 Set self dot is open equal to false. 431 00:30:49,420 --> 00:30:52,750 We're going to disable all of the prompts in our door. 432 00:30:53,310 --> 00:30:57,270 And then we can basically just do the exact same things that we did in here. 433 00:30:57,270 --> 00:30:59,550 I'm just going to copy all of this. 434 00:31:00,990 --> 00:31:03,330 We get our tween info, blah blah blah. 435 00:31:03,330 --> 00:31:09,510 And we can go ahead and make this more concise because we don't have to worry about a triggered prompt. 436 00:31:10,090 --> 00:31:16,090 So if the door is single, uh, what we're going to do is we're just going to create a goal and set 437 00:31:16,090 --> 00:31:24,790 the key frame for our hinge to be equal to self dot original, uh, hinge key frame. 438 00:31:24,790 --> 00:31:27,670 Remember that property we made on this door object. 439 00:31:27,670 --> 00:31:35,770 And then we can use our better tween module script to create a tween on self dot door model dot hinge, 440 00:31:35,770 --> 00:31:39,490 pass our tween info and then pass our goal. 441 00:31:39,700 --> 00:31:42,700 And then we're just going to copy this to the exact same thing here. 442 00:31:42,700 --> 00:31:46,030 But we'll have a goal for a hinge one. 443 00:31:46,030 --> 00:31:49,870 And this is going to be original hinge one key frame. 444 00:31:49,870 --> 00:31:51,520 Copy this. 445 00:31:51,520 --> 00:31:53,950 Do the exact same thing for hinge number two. 446 00:31:56,070 --> 00:31:57,480 And then inside of better tween. 447 00:31:57,480 --> 00:31:59,670 We're going to tween first on hinge one. 448 00:31:59,670 --> 00:32:01,860 Pass goal hinge one. 449 00:32:02,840 --> 00:32:04,100 Copy this. 450 00:32:04,100 --> 00:32:07,070 Do the exact same thing for hinge number two. 451 00:32:08,910 --> 00:32:13,170 And then once that's done, we can go ahead and play the sound door closed. 452 00:32:13,170 --> 00:32:13,980 Sound. 453 00:32:14,810 --> 00:32:18,620 Uh, the parent for this can be self dot door model. 454 00:32:19,550 --> 00:32:22,910 Dot prompt part. 455 00:32:23,120 --> 00:32:29,180 And the reason I'm setting it to the prompt part is because we don't know if this door is double or 456 00:32:29,180 --> 00:32:35,030 single, so we can't really set it to be a parent of one of the doors in there, because there might 457 00:32:35,030 --> 00:32:35,540 be two. 458 00:32:35,570 --> 00:32:37,160 There might be one, we don't know. 459 00:32:37,160 --> 00:32:38,930 So we're just going to set it to the prompt part. 460 00:32:38,930 --> 00:32:40,370 Since there's only one of those. 461 00:32:41,570 --> 00:32:44,690 Again, we're going to wait for the door move duration. 462 00:32:44,690 --> 00:32:46,670 And after that is up we're going to set self. 463 00:32:46,670 --> 00:32:52,280 Dot is moving back to false and enable the prompts again back on our door. 464 00:32:52,490 --> 00:32:53,390 And guess what. 465 00:32:53,390 --> 00:32:54,110 That's it. 466 00:32:54,110 --> 00:32:56,780 Our door system should be complete. 467 00:32:56,780 --> 00:32:58,880 So let's go ahead and test it out. 468 00:32:59,680 --> 00:33:06,100 If we go into our game and hit play here, we're going to have to go through our intro scene. 469 00:33:06,130 --> 00:33:06,550 Of course. 470 00:33:06,550 --> 00:33:08,320 So we're going to have to wait for this to go by. 471 00:33:09,280 --> 00:33:10,000 Okay. 472 00:33:10,000 --> 00:33:14,590 Let's go up to our door here and let's see if we can open it. 473 00:33:14,590 --> 00:33:19,750 So we hold down E and we see the effects got applied. 474 00:33:19,750 --> 00:33:24,400 But unfortunately we did get an error on our on client tween event. 475 00:33:24,400 --> 00:33:26,500 So let's go ahead and actually see what is going on here. 476 00:33:26,500 --> 00:33:31,810 We're getting an error of unable to cast value to objects are. 477 00:33:32,530 --> 00:33:36,010 And that's why we made a typo in our tween handler. 478 00:33:36,010 --> 00:33:41,440 And here we're actually referencing the global instance data type instead of referring to the instance 479 00:33:41,440 --> 00:33:43,390 that's passed to this function. 480 00:33:43,390 --> 00:33:45,970 So capitalization is always important. 481 00:33:45,970 --> 00:33:50,380 Make sure you put that as a lowercase I and not a capital I. 482 00:33:50,410 --> 00:33:51,640 Very important. 483 00:33:52,300 --> 00:33:54,940 Okay, but our door did open. 484 00:33:54,940 --> 00:33:56,260 We did hear the sound. 485 00:33:56,260 --> 00:34:00,610 We just didn't get it tweened because we had some goofy error in our tween handler on the client. 486 00:34:00,610 --> 00:34:03,790 But let's go ahead and test this out again now that we fixed it. 487 00:34:05,680 --> 00:34:08,290 Okay, let's go ahead and test our door out now. 488 00:34:08,290 --> 00:34:10,720 So if we go up to our door, we hold down e. 489 00:34:12,130 --> 00:34:12,580 Beautiful. 490 00:34:12,580 --> 00:34:14,500 Our door opens just as we expect. 491 00:34:14,500 --> 00:34:17,620 If we hold down E on the prompt again, it should allow us to close the door. 492 00:34:18,580 --> 00:34:24,190 Door returns back to its original position, and we can go ahead and try out the prompt on the other 493 00:34:24,190 --> 00:34:26,350 side to see if our door will open the other direction. 494 00:34:26,350 --> 00:34:28,150 So we hold down E perfect. 495 00:34:28,150 --> 00:34:30,940 Our door opens the other way and we can close it. 496 00:34:31,180 --> 00:34:34,240 Now let's go ahead and try out some of these other doors like this one. 497 00:34:34,240 --> 00:34:40,330 So if we hold down E perfect, our door opens, we can close it and we should be able to open it from 498 00:34:40,330 --> 00:34:42,310 the other direction just like that. 499 00:34:42,310 --> 00:34:43,270 Amazing. 500 00:34:44,080 --> 00:34:47,500 The next door is we can go ahead and test out our our stall doors. 501 00:34:47,500 --> 00:34:51,970 So let's see if they open only one way they should come swing out this direction. 502 00:34:51,970 --> 00:34:54,190 So perfect. 503 00:34:54,640 --> 00:34:58,540 Let's say if I close myself in here and I open it again. 504 00:34:58,540 --> 00:34:59,290 Perfect. 505 00:34:59,290 --> 00:35:05,080 Only moving one way, just as we would expect. 506 00:35:10,200 --> 00:35:15,660 And currently I'm viewing the game on the server and as you can see, the effects of our tweens have 507 00:35:15,660 --> 00:35:17,880 been applied as well on the server. 508 00:35:17,880 --> 00:35:24,540 So if I go back to the client and I go and interact with this door and close it, as you can see here, 509 00:35:24,540 --> 00:35:29,220 back on the server, our door has been updated and it is now closed. 510 00:35:29,430 --> 00:35:33,030 So it seems that our game is coming together quite nicely so far. 511 00:35:33,030 --> 00:35:35,730 Keep up the good work and I'll see you in the next lecture.